package cn.edu.sgu.www.mhxysy.service.chongwu.impl;

import cn.edu.sgu.www.mhxysy.dto.chongwu.ChongwuNeidanDTO;
import cn.edu.sgu.www.mhxysy.entity.chongwu.*;
import cn.edu.sgu.www.mhxysy.enums.NeidanTypes;
import cn.edu.sgu.www.mhxysy.enums.ComprehendStatus;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.chongwu.*;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.chongwu.ChongwuNeidanService;
import cn.edu.sgu.www.mhxysy.util.MathUtils;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import cn.edu.sgu.www.mhxysy.vo.chongwu.ChongwuNeidanVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class ChongwuNeidanServiceImpl implements ChongwuNeidanService {

    private final ChongwuMapper chongwuMapper;
    private final ChongwuNeidanMapper chongwuNeidanMapper;
    private final ChongwuCategoryMapper chongwuCategoryMapper;
    private final ChongwuNeidanCategoryMapper chongwuNeidanCategoryMapper;
    private final ChongwuNeidanResonanceMapper chongwuNeidanResonanceMapper;

    @Autowired
    public ChongwuNeidanServiceImpl(
            ChongwuMapper chongwuMapper,
            ChongwuNeidanMapper chongwuNeidanMapper,
            ChongwuCategoryMapper chongwuCategoryMapper,
            ChongwuNeidanCategoryMapper chongwuNeidanCategoryMapper,
            ChongwuNeidanResonanceMapper chongwuNeidanResonanceMapper) {
        this.chongwuMapper = chongwuMapper;
        this.chongwuNeidanMapper = chongwuNeidanMapper;
        this.chongwuCategoryMapper = chongwuCategoryMapper;
        this.chongwuNeidanCategoryMapper = chongwuNeidanCategoryMapper;
        this.chongwuNeidanResonanceMapper = chongwuNeidanResonanceMapper;
    }

    @Override
    public void resonate(String neidanId) {
        ChongwuNeidan chongwuNeidan = chongwuNeidanMapper.selectById(neidanId);

        // 高级内丹才能共鸣
        if (NeidanTypes.GJND.getValue().equals(chongwuNeidan.getType())) {
            // 内丹层数不到5层，无法共鸣
            if (chongwuNeidan.getGrade() < 5) {
                throw new GlobalException(ResponseCode.FORBIDDEN, "只有内丹达到5级才可以共鸣！");
            }

            // 查询内丹共鸣的低级内丹数量
            QueryWrapper<ChongwuNeidanResonance> queryWrapper = new QueryWrapper<>();

            queryWrapper.eq("neidan_id", neidanId);

            long selectCount = chongwuNeidanResonanceMapper.selectCount(queryWrapper);

            // 内丹共鸣数量已满
            if (selectCount >= 4) {
                throw new GlobalException(ResponseCode.CONFLICT, "内丹共鸣数量已满，请选择现有共鸣的内丹进行替换~");
            }

            /*
             * 获取即将共鸣的随机低级内丹ID
             */
            // 查询该高级内丹可共鸣的低级内丹类型ID
            List<Integer> result = chongwuNeidanCategoryMapper.selectResonances(neidanId);
            // 获得随机下标
            int index = MathUtils.random(0, result.size() - 1);
            // 根据下标获取内丹类型ID
            Integer resonanceId = result.get(index);

            /*
             * 添加一条内丹共鸣
             */
            ChongwuNeidanResonance neidanResonance = new ChongwuNeidanResonance();

            neidanResonance.setId(null);
            neidanResonance.setPxh((int) (selectCount + 1));
            neidanResonance.setNeidanId(neidanId);
            neidanResonance.setResonanceId(resonanceId);

            chongwuNeidanResonanceMapper.insert(neidanResonance);

            // 得到宠物ID
            String chongwuId = chongwuNeidan.getChongwuId();

            /*
             * 满共鸣处理
             */
            // 查询宠物信息
            Chongwu chongwu = chongwuMapper.selectById(chongwuId);
            // 查询宠物类型信息
            ChongwuCategory chongwuCategory = chongwuCategoryMapper.selectById(chongwu.getCategoryId());

            // 查询内丹生效的共鸣数量
            int count = chongwuNeidanResonanceMapper.selectResonanceCount(chongwuId, neidanId);

            // 宠物内丹恰好产生共鸣的数量达到上限，为内丹增加专属内丹的共鸣
            if (count == chongwuCategory.getNeidanQuantity() - 1) {
                ChongwuNeidanResonance resonance = new ChongwuNeidanResonance();

                resonance.setId(null);
                resonance.setPxh(0);
                resonance.setNeidanId(neidanId);
                resonance.setResonanceId(chongwuCategory.getNeidanId());

                chongwuNeidanResonanceMapper.insert(resonance);
            }
        } else {
            throw new GlobalException(ResponseCode.FORBIDDEN, "只有高级内丹可以共鸣！");
        }
    }

    @Override
    public void forget(ChongwuNeidanDTO neidanDTO) {
        QueryWrapper<ChongwuNeidan> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("chongwu_id", neidanDTO.getChongwuId());
        queryWrapper.eq("location", neidanDTO.getLocation());

        ChongwuNeidan chongwuNeidan = chongwuNeidanMapper.selectOne(queryWrapper);

        // 高级内丹，删除共鸣
        if (NeidanTypes.GJND.getValue().equals(chongwuNeidan.getType())) {
            UpdateWrapper<ChongwuNeidanResonance> updateWrapper = new UpdateWrapper<>();

            updateWrapper.eq("neidan_id", chongwuNeidan.getId());

            chongwuNeidanResonanceMapper.delete(updateWrapper);
        }

        // 删除内丹
        chongwuNeidanMapper.delete(queryWrapper);
    }

    @Override
    public void improve(ChongwuNeidanDTO neidanDTO) {
        String chongwuId = neidanDTO.getChongwuId();

        QueryWrapper<ChongwuNeidan> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq(
                StringUtils.isNotEmpty(chongwuId),
                "chongwu_id", chongwuId
        );
        queryWrapper.eq(
                neidanDTO.getLocation() != null,
                "location", neidanDTO.getLocation()
        );

        List<ChongwuNeidan> list = chongwuNeidanMapper.selectList(queryWrapper);

        if (list.isEmpty()) {
            throw new GlobalException(ResponseCode.NOT_FOUND, "操作失败，该内丹不存在~");
        } else if (list.size() > 1) {
            throw new GlobalException(ResponseCode.CONFLICT, "操作失败，数据异常~");
        }

        // 得到宠物内丹信息
        ChongwuNeidan chongwuNeidan = list.get(0);
        int grade = chongwuNeidan.getGrade();

        if (++ grade <= 5) {
            /*
             * 提升内丹之后，内丹的领悟状态重新修改为0-未领悟
             * update chongwu_neidan set grade = grade + 1, comprehend_statu = 0
             * where chongwu_id = #{chongwuId} and location = #{location} and  grade <= 4
             */
            chongwuNeidanMapper.improve(neidanDTO);

            // 满级内丹考虑高级内丹共鸣
            if (grade == 5) {
                // 查询内丹类型信息
                Integer neidanId = chongwuNeidan.getNeidanId();
                ChongwuNeidanCategory chongwuNeidanCategory = chongwuNeidanCategoryMapper.selectById(neidanId);

                // 高级内丹提升到5级时触发随机一条共鸣
                if (NeidanTypes.GJND.getValue().equals(chongwuNeidanCategory.getType())) {
                    // 查询所有低级内丹类型
                    Map<String, Object> columnMap = new HashMap<>();

                    columnMap.put("type", NeidanTypes.DJND.getValue());

                    List<ChongwuNeidanCategory> result = chongwuNeidanCategoryMapper.selectByMap(columnMap);

                    // 获得随机下标
                    int index = MathUtils.random(0, result.size() - 1);

                    // 得到随机内丹类型ID
                    Integer resonanceId = result.get(index).getId();

                    // 添加一条内丹共鸣
                    ChongwuNeidanResonance chongwuNeidanResonance = new ChongwuNeidanResonance();

                    chongwuNeidanResonance.setId(null);
                    chongwuNeidanResonance.setPxh(1);
                    chongwuNeidanResonance.setNeidanId(chongwuNeidan.getId());
                    chongwuNeidanResonance.setResonanceId(resonanceId);

                    chongwuNeidanResonanceMapper.insert(chongwuNeidanResonance);
                }
            }
        }
    }

    @Override
    public void comprehend(String chongwuId, Integer location) {
        /*
         * update chongwu_neidan set comprehend_status = 1
         * where chongwu_id = #{chongwuId} and location = #{location} and comprehend_status = 0
         */
        UpdateWrapper<ChongwuNeidan> updateWrapper = new UpdateWrapper<>();

        updateWrapper.set("comprehend_status", ComprehendStatus.YLW.getValue());

        updateWrapper.eq("chongwu_id", chongwuId);
        updateWrapper.eq("location", location);
        updateWrapper.eq("comprehend_status", ComprehendStatus.WLW.getValue());

        chongwuNeidanMapper.update(updateWrapper.getEntity(), updateWrapper);
    }

    @Override
    public void resetResonate(String neidanId, Integer resonanceId) {
        QueryWrapper<ChongwuNeidanResonance> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("neidan_id", neidanId);
        queryWrapper.eq("resonance_id", resonanceId);

        ChongwuNeidanResonance resonance = chongwuNeidanResonanceMapper.selectOne(queryWrapper);

        // 查询所有可共鸣的低级内丹类型ID
        List<Integer> list = chongwuNeidanCategoryMapper.selectResonances(neidanId);

        // 生成随机下标
        int random = MathUtils.random(0, list.size() - 1);

        // 修改内丹共鸣
        UpdateWrapper<ChongwuNeidanResonance> updateWrapper = new UpdateWrapper<>();

        updateWrapper.eq("id", resonance.getId());
        updateWrapper.set("resonance_id", list.get(random));

        chongwuNeidanResonanceMapper.update(updateWrapper.getEntity(), updateWrapper);
    }

    @Override
    public void study(String chongwuId, Integer location, Integer neidanId) {
        // 通过宠物id查询宠物内丹
        Map<String, Object> columnMap = new HashMap<>();

        columnMap.put("chongwu_id", chongwuId);
        columnMap.put("neidan_id", neidanId);

        List<ChongwuNeidan> list = chongwuNeidanMapper.selectByMap(columnMap);

        if (!list.isEmpty()) {
            throw new GlobalException(ResponseCode.CONFLICT, "宠物已经学习过相同类型的内丹");
        }

        columnMap.remove("neidan_id");
        columnMap.put("location", location);

        list = chongwuNeidanMapper.selectByMap(columnMap);

        if (!list.isEmpty()) {
            throw new GlobalException(ResponseCode.CONFLICT, "宠物该位置已经学习了内丹");
        }

        ChongwuNeidanCategory chongwuNeidanCategory = chongwuNeidanCategoryMapper.selectById(neidanId);
        Integer type = chongwuNeidanCategory.getType();

        ChongwuNeidan chongwuNeidan = new ChongwuNeidan();

        chongwuNeidan.setChongwuId(chongwuId);
        chongwuNeidan.setNeidanId(neidanId);
        chongwuNeidan.setLocation(location);

        if (NeidanTypes.ZSND.getValue().equals(type)) {
            chongwuNeidan.setLocation(5);
        }

        chongwuNeidan.setId(chongwuNeidan.uuid(type));
        chongwuNeidan.setType(type);

        // 设置默认值
        if (chongwuNeidan.getGrade() == null) {
            chongwuNeidan.setGrade(1);
        }
        if (chongwuNeidan.getComprehendStatus() == null) {
            chongwuNeidan.setComprehendStatus(ComprehendStatus.WLW.getValue());
        }

        chongwuNeidanMapper.insert(chongwuNeidan);
    }

    @Override
    public Long selectResonateCount(String neidanId) {
        QueryWrapper<ChongwuNeidanResonance> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("neidan_id", neidanId);

        long count = chongwuNeidanResonanceMapper.selectCount(queryWrapper);

        if (count > 4) {
            throw new GlobalException(ResponseCode.CONFLICT, "数据异常，最多共鸣4颗内丹。");
        }

        return count;
    }

    @Override
    public List<String> selectResonates(String neidanId) {
        return chongwuNeidanMapper.selectResonates(neidanId);
    }

    @Override
    public ChongwuNeidanVO selectDetails(String neidanId) {
        return chongwuNeidanMapper.selectDetails(neidanId);
    }

    @Override
    public List<ChongwuNeidan> selectList(ChongwuNeidanDTO neidanDTO) {
        QueryWrapper<ChongwuNeidan> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq(
                StringUtils.isNotEmpty(neidanDTO.getChongwuId()),
                "chongwu_id", neidanDTO.getChongwuId()
        );
        queryWrapper.eq(
                neidanDTO.getLocation() != null,
                "location", neidanDTO.getLocation()
        );
        queryWrapper.eq(
                neidanDTO.getType() != null,
                "type", neidanDTO.getType()
        );

        return chongwuNeidanMapper.selectList(queryWrapper);
    }

    @Override
    public List<ChongwuNeidanVO> selectNeidans(ChongwuNeidanDTO neidanDTO) {
        return chongwuNeidanMapper.selectNeidans(neidanDTO);
    }

}